/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2023-2024.
 * Description: kernel pac init function.
 * Author: wanghuizhao
 * Create: 2023-11-21
 */

#include <linux/linkage.h>
#include <linux/init.h>
#include <asm/assembler.h>

#define INIT_DATA_A 0x9687
#define INIT_DATA_B 0xB4A5

.pushsection ".init.text", "ax"

/* x5: address of init_task */
SYM_CODE_START(ptrauth_init_ikey_struct)
	mov x6, x5
	add x6, x6, #THREAD_KEYS_KERNEL
	add x6, x6, #PTRAUTH_KERNEL_KEY_APIA
	mrs x25, cntpct_el0
	mrs x19, cntfrq_el0
	add x25, x25, x19, lsl #32
	add x19, x6, x30, lsl #32
	eor x25, x25, x19    //x25=init key
	mrs x19, cntpct_el0
	mul x19, x19, x25
	str x19, [x6]
	mov x19, #INIT_DATA_A
	movk x19, #INIT_DATA_B, lsl #16
	mul x25, x19, x25
	mrs x19, cntpct_el0
	mul x19, x19, x25
	str x19, [x6, #8]
	isb

	mov x6, x5
	add x6, x6, #THREAD_KEYS_KERNEL
	add x6, x6, #PTRAUTH_KERNEL_KEY_APIB
	mrs x25, cntpct_el0
	mrs x19, cntfrq_el0
	add x25, x25, x19, lsl #32
	add x19, x6, x30, lsl #32
	eor x25, x25, x19    //x25=init key
	mrs x19, cntpct_el0
	mul x19, x19, x25
	str x19, [x6]
	mov x19, #INIT_DATA_A
	movk x19, #INIT_DATA_B, lsl #16
	mul x25, x19, x25
	mrs x19, cntpct_el0
	mul x19, x19, x25
	str x19, [x6, #8]
	isb

	mov x19, xzr
	ret
SYM_CODE_END(ptrauth_init_ikey_struct)

#ifdef CONFIG_RTOS_PAC_CFI_KERNEL
#ifdef CONFIG_CONSTRUCTORS
SYM_CODE_START(ptrauth_init_globals)
	mov x22, x30
	stp x19, x20, [sp, #-16]!
	adrp    x19, __ctors_end
	adrp    x20, __ctors_start
	add x19, x19, #:lo12:__ctors_end
	add x20, x20, #:lo12:__ctors_start
	cmp x20, x19
	b.cs    4f
3:	ldr x8, [x20], #8
	blr x8
	cmp x20, x19
	b.cc    3b
4:	ldp x19, x20, [sp], #16
	mov x30, x22
	ret
SYM_CODE_END(ptrauth_init_globals)
#endif
#endif
